package definition

import (
	"fmt"
	"os"

	config "gitee.com/woodpile/wgs.ths.config.go"
	"gopkg.in/yaml.v3"
)

type Parser interface {
	Name() string
	Make() (Parser, error)
	Parse(*Context) error
}

type ParserConfig struct {
	Dir           []string `yaml:"dir,omitempty"`
	DefineSetFile string   `yaml:"defineSetFile,omitempty"`

	Plugins map[string]interface{} `yaml:"plugins,omitempty"`
}

func (*ParserConfig) Name() string {
	return "parser"
}

func (*ParserConfig) ToDefault(cfg config.IConfigDefault) {
	ac := cfg.(*ParserConfig)
	if len(ac.Dir) == 0 {
		ac.Dir = append(ac.Dir, "./src")
	}
}

var mRegParser = make(map[string]Parser, 4)

func RegParser(parser Parser) {
	if _, ok := mRegParser[parser.Name()]; ok {
		panic("Parser already reg: " + parser.Name())
	}
	mRegParser[parser.Name()] = parser
}

var mParser = make(map[string]Parser, 4)

// 执行解析
func DoParse(ctx *Context) error {
	//加载解析器
	if err := loadParser(ctx); err != nil {
		return err
	}

	for _, f := range ctx.FuncParsePre {
		if err := f(ctx); err != nil {
			return err
		}
	}

	//执行解析
	for _, parser := range mParser {
		if err := parser.Parse(ctx); err != nil {
			return err
		}
	}

	for _, f := range ctx.FuncParsePost {
		if err := f(ctx); err != nil {
			return err
		}
	}

	//执行解析后的处理
	if GlobalConfig.Parser.DefineSetFile != "" {
		bs, err := yaml.Marshal(ctx.DFSet)
		if err != nil {
			return err
		}
		if err := os.WriteFile(GlobalConfig.Parser.DefineSetFile, bs, 0o666); err != nil {
			return err
		}
	}

	return nil
}

func loadParser(ctx *Context) error {
	//按照配置的解析器名字，构造对应的解析器
	for name := range GlobalConfig.Parser.Plugins {
		pm, ok := mRegParser[name]
		if !ok {
			return fmt.Errorf("unsupported parser: %s", name)
		}
		parse, err := pm.Make()
		if err != nil {
			return err
		}
		mParser[name] = parse
	}

	return nil
}
